


var isHTMLTag = makeMap(
	'html,body,base,head,link,meta,style,title,' +
	'address,article,aside,footer,header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,' +
	'div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,' +
	'a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,' +
	's,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,' +
	'embed,object,param,source,canvas,script,noscript,del,ins,' +
	'caption,col,colgroup,table,thead,tbody,td,th,tr,' +
	'button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,' +
	'output,progress,select,textarea,' +
	'details,dialog,menu,menuitem,summary,' +
	'content,element,shadow,template,blockquote,iframe,tfoot'
);

// this map is intentionally selective, only covering SVG elements that may
// contain child elements.
var isSVG = makeMap(
	'svg,animate,circle,clippath,cursor,defs,desc,ellipse,filter,font-face,' +
	'foreignObject,g,glyph,image,line,marker,mask,missing-glyph,path,pattern,' +
	'polygon,polyline,rect,switch,symbol,text,textpath,tspan,use,view',
	true
);

var isReservedTag = function (tag) {
	return isHTMLTag(tag) || isSVG(tag)
};

function optimize(root, options) {
	if (!root) {
		return;
	}

	isStaticKey = genStaticKeys$1("");
	isPlatformReservedTag = isReservedTag 

	// first pass: mark all non-static nodes.
	markStatic$1(root);

	// second pass: mark static roots.
	markStaticRoots(root, false);
}

function genStaticKeys$1(keys) {	
	return makeMap(
	"type,tag,attrsList,attrsMap,plain,parent,children,attrs" +
		(keys ? "," + keys : "")
	);
}

// g：标记节点是否是静态节点
function markStatic$1(node) {

	node.static = isStatic(node);

	if (node.type === 1) {
		console.log("node 11111",node,node.static)
		// do not make component slot content static. this avoids
		// 1. components not able to mutate slot nodes
		// 2. static slot content fails for hot-reloading
		console.log(
			!isPlatformReservedTag(node.tag) , // 组件
			node.tag !== "slot" ,
			node.attrsMap["inline-template"] == null
		)
		if (
			!isPlatformReservedTag(node.tag) && // 组件
			node.tag !== "slot" && 
			node.attrsMap["inline-template"] == null
		) {
			return;
		}


		// g：遍历所有孩子，如果孩子 不是静态节点，那么父亲也不是静态节点
		for (var i = 0, l = node.children.length; i < l; i++) {
			var child = node.children[i];
			markStatic$1(child);

			if (!child.static) {
				node.static = false;
			}
		}

		if (node.ifConditions) {
			for (var i$1 = 1, l$1 = node.ifConditions.length; i$1 < l$1; i$1++) {
				var block = node.ifConditions[i$1].block;

				markStatic$1(block);

				console.log("判断挂靠点",block.static)

				if (!block.static) {
					node.static = false;
				}
			}
		}
	}
}

// g：标记根节点是否是静态节点
function markStaticRoots(node, isInFor) {


	if (node.type === 1) {
			
		if (node.static || node.once) {
			node.staticInFor = isInFor;
		}

		console.log(
			"根节点",

			node.static , node.children.length , node.tag,
			
			// g：不是一个空文本节点
			!(
				node.children.length === 1 &&
				node.children[0].type === 3
			)
		)	

		// For a node to qualify as a static root, it should have children that
		// are not just static text. Otherwise the cost of hoisting out will
		// outweigh the benefits and it's better off to just always render it fresh.

		if (
			node.static &&
			node.children.length &&
			// g：保证子节点不只有一个文本节点
			!(node.children.length === 1 && node.children[0].type === 3)
		) {
			node.staticRoot = true;
			return;
		} else {
			node.staticRoot = false;
		}

		if (node.children) {
			for (var i = 0, l = node.children.length; i < l; i++) {
				markStaticRoots(node.children[i], isInFor || !!node.for);
			}
		}

		if (node.ifConditions) {
			for (var i$1 = 1, l$1 = node.ifConditions.length; i$1 < l$1; i$1++) {
				markStaticRoots(node.ifConditions[i$1].block, isInFor);
			}
		}
	}
}

function isStatic(node) {

	// expression
	if (node.type === 2) return false;

	// text
	if (node.type === 3) return true;

	// console.log(node,node.tag)

	return !!(
		node.pre ||
		(
			!node.hasBindings && // no dynamic bindings
			!node.if &&
			!node.for && // not v-if or v-for or v-else
			!isBuiltInTag(node.tag) && // not a built-in
			isPlatformReservedTag(node.tag) && // not a component
			!isDirectChildOfTemplateFor(node) &&
			Object.keys(node).every(isStaticKey)
		)
	);
}

function isDirectChildOfTemplateFor(node) {
	while (node.parent) {
		node = node.parent;
		if (node.tag !== "template") {
			return false;
		}
		if (node.for) {
			return true;
		}
	}
	return false;
}
function makeMap(
	str,
	expectsLowerCase
) {

	var map = Object.create(null);
	var list = str.split(',');

	for (var i = 0; i < list.length; i++) {
		map[list[i]] = true;
	}

	return expectsLowerCase ?
			function (val) {
				// console.log('str--->',str,);
				return map[val.toLowerCase()];
			} :
			function (val) {
				return map[val];
			}
}


var isBuiltInTag = makeMap('slot,component', true);